package com.alg.code;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

import com.alibaba.fastjson.JSONObject;

public class RSACoder extends BaseCoder {
	   public static final String KEY_ALGORTHM="RSA";//
	   public static final String SIGNATURE_ALGORITHM="MD5withRSA";
		
		public static final String PUBLIC_KEY = "RSAPublicKey";//公钥
		public static final String PRIVATE_KEY = "RSAPrivateKey";//私钥
		
		/**
		 * 初始化密钥
		 * @return
		 * @throws Exception
		 */
		public static Map<String,Object> initKey() throws Exception{
			KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORTHM);
			keyPairGen.initialize(2560);
			KeyPair keyPair = keyPairGen.generateKeyPair();
			
			//公钥
			RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
			
			//私钥
			RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
			
			Map<String,Object> keyMap = new HashMap<String,Object>(2);
			keyMap.put(PUBLIC_KEY, publicKey);
			keyMap.put(PRIVATE_KEY, privateKey);
			
			return keyMap;
		}
		
		/**
		 * 取得公钥，并转化为String类型
		 * @param keyMap
		 * @return
		 * @throws Exception
		 */
		public static String getPublicKey(Map<String, Object> keyMap)throws Exception{
			Key key = (Key) keyMap.get(PUBLIC_KEY);  
			return encryptBASE64(key.getEncoded());     
		}

		/**
		 * 取得私钥，并转化为String类型
		 * @param keyMap
		 * @return
		 * @throws Exception
		 */
		public static String getPrivateKey(Map<String, Object> keyMap) throws Exception{
			Key key = (Key) keyMap.get(PRIVATE_KEY);  
			return encryptBASE64(key.getEncoded());     
		}
		
		/**
		 * 用私钥加密
		 * @param data	加密数据
		 * @param key	密钥
		 * @return
		 * @throws Exception
		 */
		public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception{
			//解密密钥
			byte[] keyBytes = decryptBASE64(key);
			
			//取私钥
			PKCS8EncodedKeySpec pkcs8EncodeKeySpec = new PKCS8EncodedKeySpec(keyBytes);
			
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
			Key priavetKey = keyFactory.generatePrivate(pkcs8EncodeKeySpec);
			
			//对数据加密
			Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.ENCRYPT_MODE, priavetKey);
			
			return cipher.doFinal(data);
		}
		
		/**
		 * 用私钥解密 * @param data 	加密数据
		 * @param key	密钥
		 * @return
		 * @throws Exception
		 */
		public static byte[] decryptByPrivateKey(byte[] data,String key) throws Exception{
			//对私钥解密
			byte[] keyBytes = decryptBASE64(key);
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
			Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.DECRYPT_MODE, privateKey);

			return cipher.doFinal(data);
		}

		
		/**
		 * 用公钥加密
		 * @param data	加密数据
		 * @param key	密钥
		 * @return
		 * @throws Exception
		 */
		public static byte[] encryptByPublicKey(byte[] data,String key)throws Exception{
			//对公钥解密
			byte[] keyBytes = decryptBASE64(key);
			//取公钥
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
			Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			
			//对数据解密
			Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.ENCRYPT_MODE, publicKey);
			
			return cipher.doFinal(data);
		}
		
		/**
		 * 用公钥解密
		 * @param data	加密数据
		 * @param key	密钥
		 * @return
		 * @throws Exception
		 */
		public static byte[] decryptByPublicKey(byte[] data,String key)throws Exception{
			//对公钥钥解密
			byte[] keyBytes = decryptBASE64(key);
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
			Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			
			//对数据解密
			Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.DECRYPT_MODE, publicKey);
			
			return cipher.doFinal(data);
		}
		
		public static String byteArrayToHexString(byte[] addr) {
			if (addr == null)
				return null;
			StringBuilder sb = new StringBuilder("");
			for (int i = 0; i < addr.length; i++) {
				int v = addr[i] & 0xFF;
				String hv = Integer.toHexString(v);
				if (hv.length() < 2) {
					sb.append(0);
				}
				sb.append(hv);
				if (i < addr.length - 1)
					sb.append(" ");
			}
			return sb.toString();
		}
		
		
		public static void main(String[] args) throws Exception {
			Map<String,Object> keys = RSACoder.initKey();
			String publicKey = RSACoder.getPublicKey(keys);
			publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmJwDQFlZ32b1E1XAtyySIMssQhbDiwcHqBMj7+HOVr0x2/8Khib6XSj4dIsIBKwwCqjxy3tHrEDRUCY+iHNo2ChqSkSfG92KWP/1Va0nZV9qlpb22AVQI5HXaIAbVNf46dF2M+BYaFJi56NAfkrvAE2izQ5D15LWhMzcBjSA6EwIDAQAB";
//			String privateKey =  RSACoder.getPrivateKey(keys);
//			System.out.println("public key:"+publicKey);
//			System.out.println("private key:"+privateKey);
			JSONObject obj = new JSONObject();
			obj.put("zjUserId", "111");
		//	String text = "hello world,we are young hello world,we are young hello world,we are younghello world,we are younghello world";
			String text = obj.toString();
			System.out.println("加密前:"+byteArrayToHexString(text.getBytes()));
			byte[] encryptData = RSACoder.encryptByPublicKey(text.getBytes(), publicKey);
			System.out.println("加密后的数据:"+BaseCoder.encryptBASE64(encryptData));
			System.out.println("加密后的长度:"+encryptData.length);
		
//			byte[] decryptData = RSACoder.decryptByPrivateKey(encryptData, privateKey);
//			String decryptText = new String(decryptData);
//			System.out.println("解密后的数据为:"+decryptText);
		}
		
}


